package com.ivvi.autoreco.opencv;

import android.graphics.Bitmap;

import org.opencv.android.Utils;
import org.opencv.core.Core;
import org.opencv.core.CvType;
import org.opencv.core.Mat;
import org.opencv.core.MatOfFloat;
import org.opencv.core.MatOfInt;
import org.opencv.core.Point;
import org.opencv.core.Scalar;
import org.opencv.imgproc.Imgproc;

import java.util.ArrayList;
import java.util.List;

/**
 * Created by duanxianping on 2017/6/7.
 */

public class Helper {

    public static Bitmap getGray(Bitmap bitmap) {
        Mat rgbMat = new Mat();
        Mat grayMat = new Mat();
        Bitmap bitmap1 = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Utils.bitmapToMat(bitmap, rgbMat);
        Imgproc.cvtColor(rgbMat, grayMat, Imgproc.COLOR_RGB2GRAY);
        Utils.matToBitmap(grayMat, bitmap1);
        return bitmap1;
    }

    public static Bitmap hist(Bitmap bitmap) {

        Bitmap histBitmap = Bitmap.createBitmap(400, 400, Bitmap.Config.ARGB_8888);

        Mat rgbMat = new Mat();
        Utils.bitmapToMat(bitmap, rgbMat);

        //分割成3个通道
        List<Mat> splitRgb = new ArrayList<>();
        Core.split(rgbMat, splitRgb);

        //设定bin数目
        MatOfInt histSize = new MatOfInt(256);

        //设定取值范围
        MatOfFloat histRange = new MatOfFloat(0, 256);
        MatOfInt channels = new MatOfInt(0);

        Mat hist_b = new Mat();
        Mat hist_g = new Mat();
        Mat hist_r = new Mat();

        Imgproc.calcHist(splitRgb.subList(0, 1), channels, new Mat(), hist_b, histSize, histRange, false);
        Imgproc.calcHist(splitRgb.subList(1, 2), channels, new Mat(), hist_g, histSize, histRange, false);
        Imgproc.calcHist(splitRgb.subList(2, 3), channels, new Mat(), hist_r, histSize, histRange, false);

        int hist_w = 400;
        int hist_h = 400;
        int bin_w = (int) Math.round(hist_w / histSize.get(0, 0)[0]);

        Mat histMat = new Mat(hist_w, hist_h, CvType.CV_8UC3, new Scalar(0, 0, 0));

        Core.normalize(hist_b, hist_b, 0, histMat.rows(), Core.NORM_MINMAX, -1, new Mat());
        Core.normalize(hist_g, hist_g, 0, histMat.rows(), Core.NORM_MINMAX, -1, new Mat());
        Core.normalize(hist_r, hist_r, 0, histMat.rows(), Core.NORM_MINMAX, -1, new Mat());


        for (int i = 1; i < histSize.get(0, 0)[0]; i++) {
            // B component or gray image
            Imgproc.line(histMat, new Point(bin_w * (i - 1), hist_h - Math.round(hist_b.get(i - 1, 0)[0])),
                    new Point(bin_w * (i), hist_h - Math.round(hist_b.get(i, 0)[0])), new Scalar(255, 0, 0), 2, 8, 0);
            // G and R components (if the image is not in gray scale)
            Imgproc.line(histMat, new Point(bin_w * (i - 1), hist_h - Math.round(hist_g.get(i - 1, 0)[0])),
                    new Point(bin_w * (i), hist_h - Math.round(hist_g.get(i, 0)[0])), new Scalar(0, 255, 0), 2, 8, 0);
            Imgproc.line(histMat, new Point(bin_w * (i - 1), hist_h - Math.round(hist_r.get(i - 1, 0)[0])),
                    new Point(bin_w * (i), hist_h - Math.round(hist_r.get(i, 0)[0])), new Scalar(0, 0, 255), 2, 8, 0);
        }

        Utils.matToBitmap(histMat, histBitmap);

        return histBitmap;

    }

    // 均衡化
    public static Bitmap equalizeHist(Bitmap bitmap) {
        Bitmap equalizeBitmap = Bitmap.createBitmap(bitmap.getWidth(), bitmap.getHeight(), Bitmap.Config.ARGB_8888);
        Mat rgbMat = new Mat();
        Mat grayMat = new Mat();
        Utils.bitmapToMat(bitmap, rgbMat);

        Imgproc.cvtColor(rgbMat, grayMat, Imgproc.COLOR_RGB2GRAY);
        Mat equalizeMat = new Mat();
        Imgproc.equalizeHist(grayMat, equalizeMat);
        Utils.matToBitmap(equalizeMat, equalizeBitmap);
        return equalizeBitmap;
    }


}
